﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Scripting;
using Microsoft.Linq.Expressions;

namespace JavascriptEngine.Runtime
{
    public class JavaScriptObject : DynamicObject
    {
        private string Name { get; set; }
        public object DefaultObjectValue { get; set; }
        private ExpandoObject _expandoObject;
        private IDictionary<string, object> _members;
        public  JavaScriptObject prototype;

        public JavaScriptObject(string name)
        {
            _members = _expandoObject = new ExpandoObject();
            Name = name;
        }
        public JavaScriptObject()
        {
            DefaultObjectValue = null;
        }
        public void Add(string memberName, object val)
        {
            _members[memberName] = val;
        }
        public void Remove(string memberName)
        {
            if (_members.ContainsKey(memberName))
                _members.Remove(memberName);
        }

        public override bool TryConvert(ConvertBinder binder, out object result)
        {
            
            return base.TryConvert(binder, out result);
        }
        // implecit conversion operators.
        public static implicit operator Double (JavaScriptObject jsObject)
        {
            return (Double)jsObject.DefaultObjectValue;
        }
        public static implicit operator JavaScriptObject(Double doubleValue)
        {
            JavaScriptObject jsObject = new JavaScriptObject();
            jsObject.DefaultObjectValue = doubleValue;
            return jsObject;
        }
        public override string ToString()
        {
            return DefaultObjectValue.ToString();
        }
    }

    public delegate JavaScriptObject FunctionBodyLambda(params JavaScriptObject[] objs);
    public class JavaScriptFunction : JavaScriptObject
    {
        public string Body { get; set; }
        public LambdaExpression Function { get; set; }

        public JavaScriptFunction()
            : base("")
        {
        }

        public JavaScriptFunction(string name)
            : base(name)
        {
        }

        public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
        {
            return base.TryInvoke(binder, args, out result);
        }
        //public JavaScriptObject Run(params JavaScriptObject[] objs)
        //{
        //    //return Function(objs);
        //    return null;
        //}
    }
}
